package com.zlyx.easy.drools.executor;

import java.util.Map;

import org.kie.api.KieBase;
import org.kie.api.runtime.KieSession;

import com.zlyx.easy.core.exception.BusinessException;
import com.zlyx.easy.drools.builder.RuleBuilder;
import com.zlyx.easy.drools.util.DroolsUtils;

/**
 * 规则验证执行器
 * 
 * @ClassName ValidateExecutor
 * @Author zhaoguang
 * @Description ValidateExecutor
 * @Date 2020/5/28 0028
 * @Version 1.0
 */
public abstract class RuleExecutor<T> extends ReadExecutor<T> {

	/**
	 * 执行规则
	 *
	 * @param ruleName
	 * @param ruleBody
	 * @return
	 * @throws Exception
	 */
	public String validate(String ruleName, RuleBuilder.RuleBody ruleBody, Map<String, String> props) throws Exception {
		ruleBody.importClass(getTClass()); // 导入类
		String rule = doFilter(ruleBody).build();
		System.out.print("\n==============================================================================\n");
		System.out.print("输出原始规则文本内容：\n\n");
		System.out.print(rule);
		System.out.print("\n==============================================================================\n");
		rule = DroolsUtils.render(rule, ruleName, ruleBody.props());
		System.out.print("\n\n输出渲染后规则文本内容：\n\n");
		System.out.print(rule);
		System.out.print("\n==============================================================================\n");
		T context = initContext();
		if (context == null) {
			BusinessException.throwException("规则执行上下文没有设置");
		}
		try {
			KieBase kieBase = DroolsUtils.initKieBase(rule);
			if (kieBase == null) {
				BusinessException.throwException("规则引擎未设置");
			}
			KieSession kieSession = kieBase.newKieSession();
			System.out.print("\n\n执行开始规则：\n\n");
			kieSession.insert(context);
			kieSession.fireAllRules();
			kieSession.dispose();
			System.out.print("\n\n规则执行完毕\n\n");
			System.out.print("\n==============================================================================\n");
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		return rule;
	}

	/**
	 * 初始化规则上下文
	 *
	 * @return
	 */
	public abstract T initContext() throws Exception;

}
